package com.zzx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzx.domain.LoginUser;
import com.zzx.domain.Manager;
import com.zzx.domain.Role;
import com.zzx.domain.Vo.*;
import com.zzx.domain.tv.AddUser;
import com.zzx.domain.tv.UpdateUser;
import com.zzx.exception.ExceptionState;
import com.zzx.exception.SystemException;
import com.zzx.mapper.ManagerMapper;
import com.zzx.service.ManagerService;
import com.zzx.service.RoleService;
import com.zzx.util.JwtUtil;
import com.zzx.util.ResponseResult;
import com.zzx.util.SecurityContextHolderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 管理员表(Manager)表服务实现类
 *
 * @author makejava
 * @since 2022-07-31 13:51:21
 */
@Service
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, Manager> implements ManagerService {

    /*身份认证管理器*/
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public ResponseResult<Manager> login(Manager manager) {
        UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(manager.getMgName(), manager.getMgPwd());
        Authentication authentication = null;
       try{
            authentication = authenticationManager.authenticate(user);
       }catch (Exception e){
           throw  new RuntimeException(e.getMessage());
       }

        if(Objects.isNull(authentication))
            throw  new RuntimeException("用户名或者密码错误");
        /*返回用户信息*/
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Integer mgId = loginUser.getManager().getMgId();
//        /*生成token*/
        String token = JwtUtil.createJWT(mgId.toString());

        /*把登录信息存储到redis中*/
        redisTemplate.opsForValue().set("manage-"+mgId,loginUser);
        Map map = new HashMap();
        map.put("token",token);
        return new ResponseResult("登录成功", ExceptionState.OK,map);
    }

    @Override
    public ResponseResult<Manager> logout() {
        /*通过全局对象来获取当前用户信息*/
//        LoginUser loginUser = SecurityContextHolderUtils.getLoginUser();
        /*从redis中删除*/
        redisTemplate.opsForValue().get("manage-" + SecurityContextHolderUtils.getId());
        return ResponseResult.Ok("退出登录成功",ExceptionState.OK);
    }

    @Override
    public ResponseResult<GetUserVo> getUser(Integer id) {
        Manager byId = getById(id);
        GetUserVo getUserVo = setGetUserVo(byId);
        return new ResponseResult<>("查询成功",ExceptionState.OK,getUserVo);
    }

    /**
     * 获取用户列表 分页
     * @param query
     * @param pagenum
     * @param pagesize
     * @return
     */
    @Override
    @Transactional
    public ResponseResult<Object> getUsers(String query, Integer pagenum, Integer pagesize) {
        /*创建分页对象*/
        Page<Manager> page = new Page<Manager>(pagenum, pagesize) {
        };
        /*查询用户*/
        LambdaQueryWrapper<Manager> wrapper = new LambdaQueryWrapper<>();
        /*判断query参数是否存在 通过查询名称*/
        wrapper.eq(StringUtils.hasText(query),Manager::getMgName,query);
        wrapper.orderByAsc(Manager::getMgId);

        page(page,wrapper);
        List<UsersVo> collect = page.getRecords().stream().map(item -> {
            /*查询角色名称*/
            Role byId = roleService.getById(item.getRoleId());
            return new UsersVo(item.getMgId(), item.getMgName(), item.getMgMobile(), 1, item.getMgEmail(), item.getMgTime(), item.getMgState() == 1 ? true : false, Objects.isNull(byId) ? null : byId.getRoleName());
            /*拼接*/
        }).collect(Collectors.toList());
        Map<String,Object> map = new HashMap();
        map.put("total",page.getTotal());
        map.put("pagenum",page.getCurrent());
        map.put("users",collect);
        return new ResponseResult("获取成功",ExceptionState.OK,map);
    }

    /**
     * 更新用户状态
     * @param uid
     * @param type
     * @return
     */
    @Override
    public ResponseResult<UserStateVo> setState(Integer uid, Boolean type) {
        LambdaUpdateWrapper<Manager> wrapper = new LambdaUpdateWrapper();
        wrapper.eq(Manager::getMgId,uid);
        wrapper.set(Manager::getMgState,type);
        /*判断是否修改成功*/
        boolean update = update(wrapper);
       if(update==false) throw new SystemException(ExceptionState.NOUPDATE);
       /*用户状态修改后再查询*/
        Manager byId = getById(uid);
        UserStateVo userStateVo = new UserStateVo(byId.getMgId(), byId.getRoleId(), byId.getMgName(), byId.getMgMobile(), byId.getMgEmail(), byId.getMgState());
        return new ResponseResult<>("设置状态成功",ExceptionState.OK,userStateVo);
    }

    /**
     * 添加用户
     * @param addUser
     * @return
     */
    @Override
    @Transactional
    public ResponseResult AddUser(AddUser addUser) {
        addUser.setPassword(passwordEncoder.encode(addUser.getPassword()));
        Manager manager = new Manager();
        manager.setMgName(addUser.getUsername());
        manager.setMgPwd(addUser.getPassword());
        manager.setMgEmail(addUser.getEmail());
        manager.setMgMobile(addUser.getMobile());
        /*添加记录 因为是引用数据类型就有id*/
        boolean save = save(manager);
        if(save==false) throw new SystemException(ExceptionState.NOISADDUSER);
        Manager byId = getById(manager.getMgId());
        AddUserVo addUserVo = new AddUserVo(byId.getMgId(), byId.getRoleId(), byId.getMgName(), byId.getMgMobile(), byId.getMgEmail());
        return new ResponseResult("用户创建成功",ExceptionState.CREATED,addUserVo);
    }

    /**
     * 删除单个用户
     * @param id
     * @return
     */
    @Override
    public ResponseResult DeleteUser(Integer id) {
        boolean b = removeById(id);
        if(b==false) throw new SystemException(ExceptionState.NODELETE);
        return new ResponseResult("删除成功",ExceptionState.OK);
    }

    /**
     * 更新用户
     * @param id
     * @param updateUser
     * @return
     */
    @Override
    public ResponseResult UpdateUser(Integer id,UpdateUser updateUser) {
        Manager manager = new Manager();
        manager.setMgMobile(updateUser.getMobile());
        manager.setMgEmail(updateUser.getEmail());
        manager.setMgId(id);
        boolean b = updateById(manager);
        if(b==false) throw new SystemException(ExceptionState.NOUPDATE);
        return new ResponseResult("更新成功",ExceptionState.OK);
    }

    /**
     * 分配角色
     * @param id
     * @param userVo
     * @return
     */
    @Override
    public ResponseResult setRole(Integer id, AddUserVo userVo) {
        LambdaUpdateWrapper<Manager> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Manager::getRoleId,userVo.getRid());
        wrapper.eq(Manager::getMgId,id);

        boolean update = update(wrapper);
        if(update==false) throw new SystemException(ExceptionState.NOUPDATE);
        return new ResponseResult("设置角色成功",ExceptionState.OK,update);
    }

    private GetUserVo setGetUserVo(Manager manager){
        return new GetUserVo(manager.getMgId(),manager.getRoleId(),manager.getMgName(),manager.getMgMobile(),manager.getMgEmail());

    }
}

